package org.jeecg.modules.bl.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.util.DateUtils;
import org.jeecg.modules.arc.entity.BasePeriod;
import org.jeecg.modules.arc.service.IBasePeriodService;
import org.jeecg.modules.arc.service.IBaseWaterPricesService;
import org.jeecg.modules.arc.vo.BaseWaterPricesVo;
import org.jeecg.modules.bl.entity.BlExpenses;
import org.jeecg.modules.bl.entity.BlSubExpenses;
import org.jeecg.modules.bl.mapper.BlExpensesMapper;
import org.jeecg.modules.bl.mapper.BlSubExpensesMapper;
import org.jeecg.modules.bl.service.IBlExpensesService;
import org.jeecg.modules.bl.vo.BlReceiFeeCountVo;
import org.jeecg.modules.bl.vo.ChgFeeItemVo;
import org.jeecg.modules.bl.vo.RecordMEArrearVo;
import org.jeecg.modules.chg.entity.ChgArrearExpenses;
import org.jeecg.modules.chg.entity.ChgArrears;
import org.jeecg.modules.chg.entity.ChgSubArrear;
import org.jeecg.modules.chg.service.IChgArrearExpensesService;
import org.jeecg.modules.chg.service.IChgArrearsService;
import org.jeecg.modules.chg.service.IChgSubArrearService;
import org.jeecg.modules.chg.vo.ChgArrearsPage;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.*;

/**
 * @Description: 计费清单
 * @Author: jeecg-boot
 * @Date:   2022-02-13
 * @Version: V1.0
 */
@Service
public class BlExpensesServiceImpl extends ServiceImpl<BlExpensesMapper, BlExpenses> implements IBlExpensesService {
	@Resource
	private BlExpensesMapper blExpensesMapper;
	@Resource
	private BlSubExpensesMapper blSubExpensesMapper;
	@Autowired
	private IBasePeriodService basePeriodService;
	@Autowired
	private IBaseWaterPricesService waterPricesService;
	@Autowired
	private IChgArrearsService chgArrearsService;
	@Autowired
	private IChgSubArrearService chgSubArrearService;
	@Autowired
	private IChgArrearExpensesService arrearExpensesService;

	@Override
	@Transactional
	public void saveMain(BlExpenses blExpenses, List<BlSubExpenses> blSubExpensesList,String waterReadCycle) {

		if("8".equals(waterReadCycle)){
			//一月多抄的
			blExpensesMapper.insert(blExpenses);
		}else{
			List<BlExpenses> expensesList = blExpensesMapper.selectList(
					new LambdaQueryWrapper<BlExpenses>()
							.eq(BlExpenses::getCustomerId, blExpenses.getCustomerId())
							.eq(BlExpenses::getReadMonth, blExpenses.getReadMonth())
							.eq(BlExpenses::getFinancialMonth, blExpenses.getFinancialMonth())
							.eq(BlExpenses::getDelFlag, 0).eq(BlExpenses::getIsValid, 1));
			if(null != expensesList && expensesList.size()>0){
				//同一水表在水量审核前就存在计费记录的是杂项
				BlExpenses oldExpenses = expensesList.get(0);
				//把杂项金额直接设置本次计费记录
				blExpenses.setAlienMoney(oldExpenses.getAlienMoney());
				blExpenses.setMoney(blExpenses.getMoney().add(oldExpenses.getAlienMoney()));
				blExpenses.setId(oldExpenses.getId());
				//把杂项明细-已存在，不需操作

				blExpensesMapper.updateById(blExpenses);
			}else{
				blExpensesMapper.insert(blExpenses);
			}
		}

		if(blSubExpensesList!=null && blSubExpensesList.size()>0) {
			for(BlSubExpenses entity:blSubExpensesList) {
				//外键设置
				entity.setExpenseId(blExpenses.getId());
				blSubExpensesMapper.insert(entity);
			}
		}
	}
	@Override
	@Transactional
	public void saveAlienMain(BlExpenses blExpenses, List<BlSubExpenses> blSubExpensesList) {
		BasePeriod basePeriod = basePeriodService.getOne(
				new LambdaQueryWrapper<BasePeriod>()
				.eq(BasePeriod::getIsUsed,1));
		//当前财务会计期间月份
		String finMonth = basePeriod.getMonth();
		//当前抄表月份
		String readMonth = DateUtils.getDate("yyyyMM");
		BigDecimal zero = new BigDecimal(0.0);

		List<BlExpenses> blExpenseLs = blExpensesMapper.selectList(new LambdaQueryWrapper<BlExpenses>()
				.eq(BlExpenses::getCustomerId, blExpenses.getCustomerId())
				.eq(BlExpenses::getReadMonth, readMonth)
				.eq(BlExpenses::getFinancialMonth, finMonth)
				.eq(BlExpenses::getDelFlag, 0).eq(BlExpenses::getIsValid, 1));
		if(null != blExpenseLs && blExpenseLs.size()>0){
			BlExpenses expenses = blExpenseLs.get(0);
			expenses.setAlienMoney(expenses.getAlienMoney().add(blExpenses.getAlienMoney()));
			expenses.setMoney(expenses.getMoney().add(blExpenses.getAlienMoney()));
			blExpensesMapper.updateById(expenses);
			blExpenses=expenses;

			/**保存计费明细*/
			blSubExpensesList=createSubExpenses(blExpenses,blSubExpensesList);

			//欠费计费关联表
			List<ChgArrearExpenses> arrearExpensesLs = arrearExpensesService.list(
					new LambdaQueryWrapper<ChgArrearExpenses>()
					.eq(ChgArrearExpenses::getExpenseId, expenses.getId())
					.eq(ChgArrearExpenses::getDelFlag, 0));
			if(null != arrearExpensesLs && arrearExpensesLs.size()>0){
				for (ChgArrearExpenses arrearExpenses : arrearExpensesLs) {
					String arrearId = arrearExpenses.getArrearId();
					//已存在的计费记录-直接增加杂项部分
					ChgArrears arrears = chgArrearsService.getById(arrearId);
					arrears.setAlienMoney(arrears.getAlienMoney().add(blExpenses.getAlienMoney()));
					arrears.setMoney(arrears.getMoney().add(blExpenses.getAlienMoney()));
					arrears.setArrearMoney(arrears.getArrearMoney().add(blExpenses.getAlienMoney()));
					chgArrearsService.updateById(arrears);

					//欠费明细 增加杂项的
					for (BlSubExpenses blSubExpenses : blSubExpensesList) {
						ChgSubArrear subArrears = new ChgSubArrear();
						subArrears.setArrearId(arrearId);
						subArrears.setSubExpenseId(blSubExpenses.getId());
						subArrears.setItemCode(blSubExpenses.getItemCode());
						subArrears.setPriceId(blSubExpenses.getPriceId());
						subArrears.setNatureId(blSubExpenses.getNatureId());
						subArrears.setTierNo(blSubExpenses.getTierNo());
						subArrears.setPrice(blSubExpenses.getPrice());
						subArrears.setAmount(blSubExpenses.getAmount());
						subArrears.setArrearAmount(subArrears.getAmount());
						subArrears.setTotalMoney(blSubExpenses.getTotalMoney());
						subArrears.setVatMoney(blSubExpenses.getVatMoney());
						subArrears.setDiscountMoney(blSubExpenses.getDiscountMoney());
						subArrears.setMoney(blSubExpenses.getMoney());
						subArrears.setArrearMoney(subArrears.getMoney());
						subArrears.setRecivedMoney(new BigDecimal(0.0));
						subArrears.setIsLocked(0);
						subArrears.setSyncFlag(0);
						chgSubArrearService.save(subArrears);
					}
				}
			}
		}else {
			blExpenses.setReadMonth(readMonth);
			blExpenses.setFinancialMonth(finMonth);
			blExpenses.setFinancialDate(new Date());
			blExpenses.setAmount(zero);
			blExpenses.setDiscountMoney(zero);
			blExpenses.setVatMoney(zero);
			blExpenses.setTotalMoney(zero);	//专用水费值
			//Money 前端过来值
			blExpenses.setAlienMoney(blExpenses.getAlienMoney());
			blExpenses.setMoney(blExpenses.getAlienMoney());
			blExpensesMapper.insert(blExpenses);

			/**保存计费明细*/
			createSubExpenses(blExpenses,blSubExpensesList);

			//不存在欠费记录，创建
			ChgArrearsPage arrearsPage=chgArrearsService.createArrears(0
					, null
					,blExpenses ,blSubExpensesList);

			ChgArrears arrears = new ChgArrears();
			BeanUtils.copyProperties(arrearsPage, arrears);
			chgArrearsService.saveMain(arrears,arrearsPage.getChgSubArrearList(),"1");
		}
	}

	/**创建计费明细*/
	private List<BlSubExpenses> createSubExpenses(BlExpenses blExpenses,List<BlSubExpenses> blSubExpensesList) {
		BigDecimal zero = new BigDecimal(0.0);
		Set<String>natureSet=new HashSet<>();
		Map<String,BaseWaterPricesVo>natureMap=new HashMap<>();

		if(blSubExpensesList!=null && blSubExpensesList.size()>0) {
			for(BlSubExpenses entity:blSubExpensesList) {
				//外键设置
				entity.setExpenseId(blExpenses.getId());

				if(!natureSet.contains(entity.getNatureId())){
					natureSet.add(entity.getNatureId());
					//用水性质对应用水价格
					List<BaseWaterPricesVo> pricesVos = waterPricesService.queryWaterPriceByNatureId(
							entity.getNatureId(),"1");
					if(null != pricesVos && pricesVos.size()>0){
						BaseWaterPricesVo pricesVo = pricesVos.get(0);
						entity.setPriceId(pricesVo.getPriceId());
						entity.setItemCode(pricesVo.getCode());
					}
					natureMap.put(entity.getNatureId(),pricesVos.get(0));
				}else{
					BaseWaterPricesVo pricesVo=natureMap.get(entity.getNatureId());
					entity.setPriceId(pricesVo.getPriceId());
					entity.setItemCode(pricesVo.getCode());
				}
				entity.setTierNo(0);
				entity.setDiscountMoney(zero);
				entity.setVatMoney(zero);
				entity.setMoney(entity.getTotalMoney());
				entity.setPrice(new BigDecimal(1.0));
				blSubExpensesMapper.insert(entity);
			}
		}
		return blSubExpensesList;
	}


	@Override
	@Transactional
	public void updateAlienMain(BlExpenses blExpenses,List<BlSubExpenses> blSubExpensesList) {

	}
	@Override
	@Transactional
	public void updateMain(BlExpenses blExpenses,List<BlSubExpenses> blSubExpensesList) {
		blExpensesMapper.updateById(blExpenses);

		//1.先删除子表数据
		blSubExpensesMapper.deleteByMainId(blExpenses.getId());

		//2.子表数据重新插入
		if(blSubExpensesList!=null && blSubExpensesList.size()>0) {
			for(BlSubExpenses entity:blSubExpensesList) {
				//外键设置
				entity.setExpenseId(blExpenses.getId());
				blSubExpensesMapper.insert(entity);
			}
		}
	}

	@Override
	@Transactional
	public void delMain(String id) {
		blSubExpensesMapper.deleteByMainId(id);
		blExpensesMapper.deleteById(id);
	}

	//删除水费明细
	@Override
	public void delSubByMainId(String id) {
		blSubExpensesMapper.deleteByMainId(id);
	}

	//删除杂项费用
	@Override
	@Transactional
	public Result<?> delAlienMain(String id) {

		//计费-欠费 ID对应Map
		HashMap<String, String> map = new HashMap<>();

		BigDecimal alienDecimal = new BigDecimal(0.0);
		List<BlSubExpenses> subExpenses = blSubExpensesMapper.selectAlienArrearByMainId(id);
		if(null != subExpenses && subExpenses.size()>0){
			for (BlSubExpenses subExpens : subExpenses) {
				alienDecimal = alienDecimal.add(subExpens.getTotalMoney());
				if(!map.containsKey(subExpens.getExpenseId())){
					map.put(subExpens.getExpenseId(),subExpens.getArrearId());
				}
			}
		}else{
			//已收过费了，欠费记录不存在
			return Result.error("杂项已收费，不能删除");
		}

		//删除杂项-计费明细
		blSubExpensesMapper.deleteAlienByMainId(id);

		BlExpenses expenses = blExpensesMapper.selectById(id);
		if(expenses.getTotalMoney().doubleValue()>0){
			//存在水费大于0-合并计费的 减掉杂项部分费用
			expenses.setAlienMoney(expenses.getAlienMoney().subtract(alienDecimal));
			expenses.setMoney(expenses.getMoney().subtract(alienDecimal));
			blExpensesMapper.updateById(expenses);
			//删除杂项计费明细
			blSubExpensesMapper.deleteAlienByMainId(expenses.getId());

			ChgArrears arrears = chgArrearsService.getById(map.get(expenses.getId()));
			if(null != arrears){
				arrears.setAlienMoney(arrears.getAlienMoney().subtract(alienDecimal));
				arrears.setMoney(arrears.getMoney().subtract(alienDecimal));
				arrears.setArrearMoney(arrears.getArrearMoney().subtract(alienDecimal));
				chgArrearsService.updateById(arrears);

				//删除杂项欠费明细
				chgArrearsService.delAlienSubByMainId(arrears.getId());
			}

		}else{
			//直接删除不存在水费的 杂项计费
			blExpensesMapper.deleteById(id);
			//删除杂项计费明细
			blSubExpensesMapper.deleteAlienByMainId(expenses.getId());

			//直接删除不存在水费的 杂项欠费及杂项欠费明细
			chgArrearsService.delAlienMain(map.get(expenses.getId()));
		}

		return Result.OK("删除成功");
	}

	@Override
	@Transactional
	public void delBatchMain(Collection<? extends Serializable> idList) {
		for(Serializable id:idList) {
			blSubExpensesMapper.deleteByMainId(id.toString());
			blExpensesMapper.deleteById(id);
		}
	}
	@Override
	@Transactional
	public void delAlienBatchMain(Collection<? extends Serializable> idList) {
		for(Serializable id:idList) {
			delAlienMain((String) id);
		}
	}

	@Override
	public List<RecordMEArrearVo> queryRecordMEArrear(String recordId) {
		return blExpensesMapper.queryRecordMEArrear(recordId);
	}
	@Override
	public List<ChgFeeItemVo> queryFeeBill(List<String> rdIds,String beginTime,String endTime) {
		return blExpensesMapper.queryFeeBill(rdIds,beginTime,endTime);
	}

	@Override
	public List<BlReceiFeeCountVo>receivableFeeCount(String financialMonth){
		return 	blExpensesMapper.receivableFeeCount(financialMonth);
	}

}
